
namespace TomatoBreak.UnitSpecs
{
    using System.Collections.Generic;
    using System.Diagnostics;

    using AutoPoco;
    using AutoPoco.DataSources;
    using AutoPoco.Engine;

    using TomatoBreak.DomainObjects;
    using Infrastructure;

    public class ObjectMother
    {
        private const int DefaultCount = 5;

        [DebuggerStepThrough]
        public static User CreateUser()
        {
            return CreateUserSession().Single<User>().Get();
        }

        [DebuggerStepThrough]
        public static IEnumerable<User> CreateUsers(int count = DefaultCount)
        {
            return CreateUserSession().List<User>(count).Get();
        }

        [DebuggerStepThrough]
        public static Task CreateTask(User user = null)
        {
            return CreateTaskSession(user).Single<Task>().Get();
        }

        [DebuggerStepThrough]
        public static IEnumerable<Task> CreateTasks(int count = DefaultCount, User user = null)
        {
            return CreateTaskSession(user).List<Task>(count).Get();
        }

        private static IGenerationSession CreateTaskSession(User user = null)
        {
            return AutoPocoContainer.Configure(x =>
                                                    x.AddFromAssemblyContainingType<User>()
                                                     .Include<Task>()
                                                     .Setup(t => t.Id).Use<GuidSource>()
                                                     .Setup(t => t.Name).Use<RandomStringSource>(4, 256)
                                                     .Setup(t => t.CreatedAt).Value(Clock.UtcNow())
                                                     .Setup(t => t.User).Value(user ?? CreateUser()))
                                    .CreateSession();
        }

        private static IGenerationSession CreateUserSession()
        {
            return AutoPocoContainer.Configure(x =>
                                                    x.AddFromAssemblyContainingType<User>()
                                                     .Include<User>()
                                                     .Setup(u => u.Id).Use<GuidSource>()
                                                     .Setup(u => u.UserName).Use<RandomStringSource>(4, 32)
                                                     .Setup(u => u.Password).Use<RandomStringSource>(4, 64)
                                                     .Setup(u => u.Salt).Use<RandomStringSource>(4, 64)
                                                     .Setup(u => u.Email).Use<EmailAddressSource>())
                                    .CreateSession();
        }
    }
}